package cn.yj.core.business.service;

import cn.yj.annotation.pagehelper.page.Page;
import cn.yj.cgs.dba.entity.Integral;
import cn.yj.cgs.dba.entity.IntegralWater;
import cn.yj.cgs.dba.entity.Message;
import cn.yj.cgs.dba.entity.vo.IntegralWaterPcVo;
import cn.yj.cgs.dba.mapper.IntegralMapper;
import cn.yj.cgs.dba.mapper.IntegralWaterMapper;
import cn.yj.cgs.dba.mapper.MessageMapper;
import cn.yj.common.Enums;
import cn.yj.common.NameValue;
import cn.yj.commons.utils.BigDecimalUtils;
import cn.yj.commons.utils.MapUtils;
import cn.yj.commons.utils.StringUtils;
import cn.yj.params.check.annotation.CheckObjectValue;
import cn.yj.params.check.annotation.KeyValue;
import cn.yj.params.check.annotation.Require;
import cn.yj.tools.exception.ServiceException;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static cn.yj.commons.utils.FilterNull.isNull;

/**
 * @author 永健
 * @since 2021-06-09 17:09
 */
@Service
public class IntegralService extends ServiceImpl<IntegralMapper, Integral> {

    @Resource
    private IntegralWaterMapper waterMapper;

    @Resource
    private MessageMapper messageMapper;

    public Page<IntegralWaterPcVo> waterPageList(Map<String, Object> params, @Require Page<IntegralWaterPcVo> page) {
        waterMapper.pageList(params, page);
        return page;
    }


    private static final Map<String, Object> DICT_MAP = new ConcurrentHashMap<>();

    public Map<String, Object> getWaterStatusSourceType() {

        if (!DICT_MAP.isEmpty()) {
            return DICT_MAP;
        }
        Enums.IntegralWater.SOURCE[] values = Enums.IntegralWater.SOURCE.values();
        List<NameValue> sources = new ArrayList<>();
        for (int i = 0; i < values.length; i++) {
            Enums.IntegralWater.SOURCE value = values[i];
            sources.add(new NameValue(value.getMsg(), value.name()));
        }

        Enums.IntegralWater.TYPE[] typesEnums = Enums.IntegralWater.TYPE.values();
        List<NameValue> types = new ArrayList<>();
        for (int i = 0; i < typesEnums.length; i++) {
            Enums.IntegralWater.TYPE value = typesEnums[i];
            types.add(new NameValue(value.getMsg(), value.name()));
        }

        Enums.IntegralWater.STATUS[] statusEnums = Enums.IntegralWater.STATUS.values();
        List<NameValue> status = new ArrayList<>();
        for (int i = 0; i < statusEnums.length; i++) {
            Enums.IntegralWater.STATUS value = statusEnums[i];
            status.add(new NameValue(value.getMsg(), value.name()));
        }

        DICT_MAP.put("source", sources);
        DICT_MAP.put("type", types);
        DICT_MAP.put("status", status);

        return DICT_MAP;
    }

    /**
     * 积分提现处理。修改状态
     *
     * @param params 参数
     */
    @Transactional
    @CheckObjectValue(keyValue = @KeyValue(type = Map.class, name = {"userCode", "waterNo", "statusCode"}))
    public boolean waterCashOutUpdate(Map<String, Object> params) {
        String userCode = MapUtils.getStringVal(params, "userCode");
        String waterNo = MapUtils.getStringVal(params, "waterNo");
        String statusCode = MapUtils.getStringVal(params, "statusCode");
        IntegralWater integralWater = waterMapper.selectByNoForUpdate(waterNo);
        isNull(integralWater, "找不到该提现记录");
        if (!integralWater.getUserCode().equals(userCode)) {
            throw new ServiceException("该记录与用户信息不匹配");
        }
        Enums.IntegralWater.STATUS statusDb = integralWater.getStatus();

        if (!statusDb.name().equals(Enums.IntegralWater.STATUS.doing.name())) {
            throw new ServiceException("当前提现已经处理过，不能重复处理");
        }

        // 状态相同不更改
        if (statusDb.name().equals(statusCode)) {
            return true;
        }

        Integral integral = baseMapper.selectIntegralByUserCodeForUpdate(userCode);
        int row = 1;
        String noticeMsg="你的积分提现成功啦～";
        if (statusCode.equals(Enums.IntegralWater.STATUS.fail.name())) {
            // 积分回退
            integral.setIntegral(BigDecimalUtils.add(integral.getIntegral(), integralWater.getIntegral()));
            // 积分更新
            row = baseMapper.updateById(integral);
            String remark = MapUtils.getStringVal(params, "remark");
            noticeMsg= StringUtils.isBlank(remark)?"积分提现失败~":remark;
        }

        messageMapper.insert(new Message(noticeMsg,"积分提现通知",userCode));

        integralWater.setStatus(Enums.IntegralWater.STATUS.valueOf(statusCode));
        return row > Enums.Common.ZERO && waterMapper.updateById(integralWater) > Enums.Common.ZERO;
    }
}
